package com.ntty.factory;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;

import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpContentCompressor;
import io.netty.handler.codec.http.HttpContentDecompressor;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpRequestEncoder;
import io.netty.handler.codec.http.HttpResponseDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.HttpServerExpectContinueHandler;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

public class HttpPipelineFactory {
	public static void regSsl(ChannelPipeline pipeline, SSLEngine engine) {
		pipeline.addFirst("ssl", new SslHandler(engine));
	}

	public static void regSsl(ChannelPipeline pipeline, SSLContext context, boolean 是客户端, boolean 是否开启TLS)
			throws Exception {
		SSLEngine engine = context.createSSLEngine();
		engine.setUseClientMode(是客户端);
		pipeline.addFirst("ssl", new SslHandler(engine, 是否开启TLS));
	}

	public static void reg发送方解码器(ChannelPipeline pipeline) {
		pipeline.addLast("decoder", new HttpResponseDecoder());
		pipeline.addLast("encoder", new HttpRequestEncoder());
	}

	public static void reg接收方解码器(ChannelPipeline pipeline) {
		//HttpRequestDecoder 即把 ByteBuf 解码到 HttpRequest 和 HttpContent。
		pipeline.addLast("decoder", new HttpRequestDecoder());
		//HttpResponseEncoder 即把 HttpResponse 或 HttpContent 编码到 ByteBuf。
		pipeline.addLast("encoder", new HttpResponseEncoder());
		//HttpServerCodec 即 HttpRequestDecoder 和 HttpResponseEncoder 的结合。
	}



	/** 针对http协议进行编解码,将请求和应答消息解码为HTTP消息*/
	
	public static void reg服务端Http编码(ChannelPipeline pipeline) {
		pipeline.addLast("Servercodec", new HttpServerCodec());
	}

	public static void reg客户端Http编码(ChannelPipeline pipeline) {
		pipeline.addLast("Clientcodec", new HttpClientCodec());
	}
	public static void reg压缩器(ChannelPipeline pipeline) {
		// 写入时压缩
		pipeline.addLast("compressor", new HttpContentCompressor());
	}
	public static void reg解压缩器(ChannelPipeline pipeline) {
		// 读取时解压缩
		pipeline.addLast("decompressor", new HttpContentDecompressor());
	}

	/**
	 * 调用#new HttpObjectAggregator(1024*1024)方法,即通过它可以把 HttpMessage<br>
	 *  和 HttpContent 聚合成一个 FullHttpRequest 或者 FullHttpResponse <br>
	 *  （取决于是处理请求还是响应），而且它还可以帮助你在解码时忽略是否为“块”传输方式。<br>
	 *  因此，在解析 HTTP POST 请求时，请务必在 ChannelPipeline 中加上 HttpObjectAggregator。<br>
	 *  是请求时必须放在HttpServerCodec后的后面<br>
	 */
	public static void reg消息聚合(ChannelPipeline pipeline) {
		// 为了防止Dos攻击服务器，需要合理的限制消息的大小。
		pipeline.addLast("aggegator", new HttpObjectAggregator(1024 * 1024));
	}

	/**
	 * 作用是将一个Http的消息组装成一个完成的HttpRequest或者HttpResponse，
	 * 
	 * 那么具体的是什么 取决于是请求还是响应, 该Handler必须放在HttpServerCodec后的后面
	 */
	public static void reg消息聚合(ChannelPipeline pipeline, int maxsize) {
		// 为了防止Dos攻击服务器，需要合理的限制消息的大小。
		pipeline.addLast("aggegator", new HttpObjectAggregator(maxsize));
	}

	/**
	 * ChunkedWriteHandler分块写处理，文件过大会将内存撑爆
	 * 
	 * 分块写入,适用于 大数据
	 */
	public static void reg分块写入(ChannelPipeline pipeline) {
		pipeline.addLast("chunkedWrite", new ChunkedWriteHandler());
	}
	public static void reg判断服务器是否允许上传大数据(ChannelPipeline pipeline) {
		pipeline.addLast("httpServerExpectContinueHandler", new HttpServerExpectContinueHandler());
	}
}
